//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.quickserver.util.pool;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.pool.PoolableObjectFactory;

public class BasicObjectPool implements QSObjectPool {
    private static final Logger logger = Logger.getLogger(BasicObjectPool.class.getName());
    private PoolableObjectFactory factory;
    private BasicObjectPool.Config config;
    private Set activeObjects;
    private Set idleObjects;
    private volatile boolean inMaintain;

    public BasicObjectPool() {
        this.inMaintain = false;
        this.activeObjects = Collections.synchronizedSet(new HashSet());
        this.idleObjects = Collections.synchronizedSet(new HashSet());
        this.config = new BasicObjectPool.Config();
    }

    public BasicObjectPool(PoolableObjectFactory factory, BasicObjectPool.Config config) {
        this();
        this.factory = factory;
        if (config != null) {
            this.config = config;
        }

    }

    public void addObject() throws Exception {
        if (this.config.maxIdle != -1 && this.config.maxIdle <= this.getNumIdle()) {
            this.maintain();
        } else {
            this.idleObjects.add(this.factory.makeObject());
        }

    }

    public Object borrowObject() throws Exception {
        if (this.getNumIdle() <= 0 && (this.config.maxActive == -1 || this.config.maxActive > this.getNumActive())) {
            this.addObject();
        }

        if (this.getNumIdle() <= 0) {
            throw new NoSuchElementException("No free objects! MaxActive:" + this.config.maxActive + ", NumActive:" + this.getNumActive());
        } else {
            Object obj = null;
            synchronized(this) {
                obj = this.idleObjects.iterator().next();
                this.idleObjects.remove(obj);
                this.factory.activateObject(obj);
                this.activeObjects.add(obj);
                return obj;
            }
        }
    }

    public synchronized void clear() {
        Iterator iterator = this.idleObjects.iterator();

        while(iterator.hasNext()) {
            try {
                this.invalidateObject(iterator.next());
            } catch (Exception var3) {
                logger.warning("Error in BasicObjectPool.clear : " + var3);
            }
        }

        this.idleObjects.clear();
    }

    public void close() throws Exception {
        this.clear();
        this.activeObjects.clear();
    }

    public int getNumActive() {
        return this.activeObjects.size();
    }

    public int getNumIdle() {
        return this.idleObjects.size();
    }

    public void invalidateObject(Object obj) throws Exception {
        this.factory.destroyObject(obj);
    }

    public synchronized void returnObject(Object obj) throws Exception {
        this.activeObjects.remove(obj);
        if (!this.factory.validateObject(obj)) {
            logger.finer("Object not good for return: " + obj);
        } else {
            this.factory.passivateObject(obj);
            this.idleObjects.add(obj);
            if (this.config.maxIdle != -1 && this.config.maxIdle < this.getNumIdle()) {
                this.maintain();
            }

        }
    }

    public void setFactory(PoolableObjectFactory factory) {
        this.factory = factory;
    }

    private void maintain() {
        if (!this.inMaintain) {
            this.inMaintain = true;
            logger.log(Level.FINEST, "Starting maintain: {0}", this.getNumIdle());

            while(this.getNumIdle() > this.config.maxIdle) {
                try {
                    Set var1 = this.idleObjects;
                    synchronized(this.idleObjects) {
                        Object obj = this.idleObjects.iterator().next();
                        this.idleObjects.remove(obj);
                        this.invalidateObject(obj);
                    }
                } catch (Exception var4) {
                    logger.log(Level.WARNING, "Error in BasicObjectPool.maintain : {0}", var4);
                }
            }

            this.inMaintain = false;
            logger.log(Level.FINEST, "Finished maintain: {0}", this.getNumIdle());
        }
    }

    public Iterator getAllActiveObjects() {
        List _list = new LinkedList();
        _list.addAll(this.activeObjects);
        return _list.iterator();
    }

    public Object getObjectToSynchronize() {
        return this.activeObjects;
    }

    public static class Config {
        public int maxActive = -1;
        public int maxIdle = 10;

        public Config() {
        }
    }
}
